import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';

class SceneMap {
  public camera: THREE.Camera;
  public scene: THREE.Scene = new THREE.Scene();
  public renderer: THREE.WebGLRenderer = new THREE.WebGLRenderer({
    antialias: true,
    alpha: true
  });
  public controls: any;
  public container: HTMLElement | null;
  public renderFun: Function | null;

  constructor(container: HTMLElement | null) {
    this.container = container;

    let width = this.container!.clientWidth; //窗口宽度
    let height = this.container!.clientHeight; //窗口高度
    let k = width / height; //窗口宽高比
    let s = 75; //三维场景显示范围控制系数，系数越大，显示的范围越大
    //创建相机对象
    // 正向投影
    // this.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    this.camera = new THREE.PerspectiveCamera(75, k, 1, 1000);
    this.renderer.setSize(width, height); //设置渲染区域尺寸
  }
  init = () => {
    //点光源
    let point = new THREE.PointLight(0xffffff); //代表模型的亮度
    point.position.set(0, 50, 0); //点光源位置
    this.scene.add(point); //点光源添加到场景中
    //环境光
    let ambient = new THREE.AmbientLight('white', 50);
    ambient.position.set(0, 50, 0); //环境光位置
    this.scene.add(ambient);

    let light = new THREE.DirectionalLight(0xffffff, 3);
    light.position.set(0, 50, 0); //点光源位置
    this.scene.add(light);
    // 透视投影
    this.camera.position.set(0, 90, 0); //设置相机位置
    this.camera.lookAt(this.scene.position); //设置相机方向(指向的场景对象)
    this.renderer.setClearColor(0xeeeeee, 0.0); //设置背景颜色 透明
    this.container!.appendChild(this.renderer.domElement); //body元素中插入canvas对象
    this.render(); //执行渲染
    this.createControls(); //监听窗口变化
  };
  // 渲染函数
  render = () => {
    this.renderFun && this.renderFun();
    requestAnimationFrame(this.render); //请求再次执行渲染函数render
    // this.controls.update();
    this.renderer.render(this.scene, this.camera); //执行渲染操作
  };
  renderAdd = (fun: Function | null) => {
    this.renderFun = fun;
  };

  createAxisHelper = () => {
    let axisHelper = new THREE.AxesHelper(250);
    this.scene.add(axisHelper);
  };

  addControls = () => {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
  };

  createControls = () => {
    // 监听浏览器窗口的变化
    addEventListener(
      'resize',
      (e) => {
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix();
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.setSize(
          this.container!.clientWidth,
          this.container!.clientHeight
        );
      },
      true
    );
  };
  // 添加动态模型
  addMesh(Mesh: THREE.Mesh | THREE.Points | THREE.Line) {
    this.scene.add(Mesh);
  }
}
export default SceneMap;
